﻿using FluentAssertions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NewRetail.Application.Components.Goods;
using NewRetail.Application.Components.Goods.Entity;
using NewRetail.Application.Core;
using System;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Uow;

namespace NewRetail.Api.Controllers
{
    [NewRetailRoute("goods-member-price")]
    public class GoodsMemberPriceController : BaseController<GoodsMemberPrice, GoodsMemberPricePagingDto>
    {
        private readonly IGoodsMemberPriceService goodsMemberPriceService;

        public GoodsMemberPriceController(IGoodsMemberPriceService goodsMemberPriceService)
        {
            this.goodsMemberPriceService = goodsMemberPriceService;
        }

        protected override async Task<IQueryable<GoodsMemberPrice>> FilterQueryPaging(DbContext db, IQueryable<GoodsMemberPrice> query, GoodsMemberPricePagingDto dto)
        {
            if (!string.IsNullOrWhiteSpace(dto.no))
            {
                var goodIds = db.Set<GoodsInfo>().Where(x => x.No == dto.no).Select(x => x.Id);
                query = query.Where(x => goodIds.Contains(x.goodsID));
            }

            if (!string.IsNullOrWhiteSpace(dto.warehouseId))
            {
                query = query.Where(x => x.warehouseID == dto.warehouseId);
            }

            await Task.CompletedTask;
            return query;
        }

        public override async Task<ResponseEntity<PagedResultDto<GoodsMemberPrice>>> QueryPaging([FromBody] GoodsMemberPricePagingDto dto)
        {
            var data = await base.QueryPaging(dto);

            if (data.Data?.Items?.Any() ?? false)
            {
                data.Data.Items = await this.goodsMemberPriceService.AttachGoods(data.Data.Items.ToArray());
                data.Data.Items = await this.goodsMemberPriceService.AttachWarehouse(data.Data.Items.ToArray());
            }

            return data;
        }

        protected override Task<GoodsMemberPrice> BeforeUpdate(GoodsMemberPrice entity, GoodsMemberPrice data)
        {
            entity.goodsID = data.goodsID;
            entity.warehouseID = data.warehouseID;
            entity.oldPrice = data.oldPrice;
            entity.memberPrice = data.memberPrice;
            entity.remark = data.remark;
            return base.BeforeUpdate(entity, data);
        }

        public override async Task<ResponseEntity<GoodsMemberPrice>> Save([FromBody] GoodsMemberPrice data)
        {
            var res = await this.SaveMultiple(new[] { data });
            res.ThrowIfNotSuccess();

            return new ResponseEntity<GoodsMemberPrice>().SetData(data);
        }

        [HttpPost("save-multiple")]
        public async Task<ResponseEntity<GoodsMemberPrice[]>> SaveMultiple([FromBody] GoodsMemberPrice[] data)
        {
            data.Should().NotBeNullOrEmpty();
            using var uow = this.UnitOfWorkManager.Begin(requiresNew: true, isTransactional: true);
            try
            {
                var db = await this.Repo.GetDbContextAsync();
                var goodsMemberPriceSet = db.Set<GoodsMemberPrice>();

                foreach (var m in data)
                {
                    if (string.IsNullOrWhiteSpace(m.Id))
                    {
                        await this.BeforeInsertDataInitial(m);
                        this.EntityHelper.InitEntity(m);
                        await this.BeforeInsert(m);
                        goodsMemberPriceSet.Add(m);
                    }
                    else
                    {
                        var entity = await goodsMemberPriceSet.FirstOrDefaultAsync(x => x.Id == m.Id);
                        if (entity == null)
                        {
                            throw new UserFriendlyException("更新的对象不存在");
                        }
                        await this.BeforeUpdate(entity, m);
                        this.EntityHelper.SetUpdationInfo(entity);
                    }
                }

                await db.SaveChangesAsync();

                await uow.CompleteAsync();
                return new ResponseEntity<GoodsMemberPrice[]>().SetData(data);
            }
            catch
            {
                await uow.RollbackAsync();
                throw;
            }
        }

        [HttpPost("get-goods-members-price")]
        public async Task<ResponseEntity<GoodsMemberPrice[]>> GetWarehouseMembers([FromBody] GetGoodsMemberPriceDto dto)
        {
            dto.Should().NotBeNull();
            dto.Page ??= 1;
            (dto.Page >= 1).Should().BeTrue();

            var db = await this.Repo.GetDbContextAsync();

            var query = db.Set<GoodsMemberPrice>().IgnoreQueryFilters().AsNoTracking();

            if (dto.UpdateTime != null)
            {
                query = query.Where(x => x.updateTime >= dto.UpdateTime.Value);
            }

            query = query.OrderBy(x => x.updateTime).Page(dto.Page.Value, pageSize: 100);

            var data = await query.ToArrayAsync();

            return new ResponseEntity<GoodsMemberPrice[]>().SetData(data);
        }
    }
}
